<script setup>
import {ref, onMounted, reactive, watch} from 'vue';
import {
  ElButton,
  ElTable,
  ElTableColumn,
  ElMessage,
  ElDialog,
  ElForm,
  ElInput,
  ElSelect,
  ElOption,
  ElPagination,
  ElMessageBox, genFileId
} from 'element-plus';
import {GetAdCreatives, AddAdCreative, UpdateAdCreative, DeleteAdCreative} from '@/api/index.js';
import {Plus, UploadFilled} from "@element-plus/icons-vue";

const addAdCreativeRef = ref()
const temp_file = ref()
const newAdCreative = ref({
  name: '',
  creative_type: 0,
  material_type: 0,
  height: 0,
  width: 0,
  size: 0,
  duration: 0,
});

const rules = reactive({
  name: [
    { required: true, message: "请输入创意名", trigger: "blur" },
    { min: 2, message: "创意名不能小于2位", trigger: "change" },
  ],
  width: [
    { required: true, message: "请输入宽度", trigger: "blur" },
    { type: "number", message: "宽度必须是数字", trigger: "blur" },
  ],
  height: [
    { required: true, message: "请输入高度", trigger: "blur" },
    { type: "number", message: "高度必须是数字", trigger: "blur" },
  ],
});
const adCreatives = ref([]);  // 用于存储创意数据
const totalItems = ref(0);  // 总条目数
const currentPage = ref(1);  // 当前页
const pageSize = ref(10);  // 每页条目数
const sortField = ref('');

const getAdCreatives = async () => {
  try {
    const response = await GetAdCreatives({
      page: currentPage.value,
      page_size: pageSize.value,
      order_by: sortField.value,
      search: searchText.value, // 传递搜索关键词
    });
    adCreatives.value = response.results;
    totalItems.value = response.count;
  } catch (error) {
    ElMessage.error('无法加载创意，请稍后重试');
  }
};

// 分页切换
const handlePageChange = (page) => {
  currentPage.value = page;
  getAdCreatives(); // 刷新当前广告单元的创意列表
};

// 处理排序字段变化
const handleSortChange = () => {
  getAdCreatives();
};

// 打开创意添加表单
const isAdCreativeFormVisible = ref(false);
const toggleAdCreativeForm = () => {
  isAdCreativeFormVisible.value = true;
  newAdCreative.value = {
    name: '',
    creative_type: 0,
    material_type: 0,
    height: 0,
    width: 0,
    size: 0,
    duration: 0,
  }
};

// 创建创意
const createAdCreative = async () => {
  const valid = await addAdCreativeRef.value.validate();
  if (!valid) {
    ElMessage.warning("请填写合法的数据")
    return;
  }
  let formData = new FormData()
  for (let i in newAdCreative.value){
    formData.append(i,newAdCreative.value[i])
  }
  if(temp_file.value){//file资源加入二进制数据
    formData.append('file',temp_file.value)
  }
  try {
    const res = await AddAdCreative(formData);
    await getAdCreatives();  // 刷新创意列表
    ElMessage.success(res.message);
    isAdCreativeFormVisible.value = false;
  } catch (error) {
    ElMessage.error('添加创意失败，请稍后再试');
  }
};

// 删除创意
const deleteAdCreative = (id) => {
  ElMessageBox.confirm(
      '确定删除此创意吗?',
      '删除',
      {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
      }
  ).then(async () => {
    try {
      await DeleteAdCreative(id);
      await getAdCreatives();  // 刷新创意列表
      ElMessage.success('创意删除成功');
    } catch (error) {
      ElMessage.error('删除创意失败，请稍后再试');
    }
  });
};

// 编辑创意
const isEditDialogVisible = ref(false);
const currentAdCreative = ref({});
const oldAdCreative = ref({})
const editAdCreative = (id) => {
  const creative = adCreatives.value.find(item => item.creative_id === id);
  if (creative) {
    currentAdCreative.value = {...creative};
    oldAdCreative.value = {...creative};
    isEditDialogVisible.value = true;
  } else {
    ElMessage.error('未找到对应的创意');
  }
};

// 更新创意
const updateAdCreative = async () => {
  if (currentAdCreative.value && currentAdCreative.value.url) {
    delete currentAdCreative.value.url; //url不需要前端传
  }
  if (currentAdCreative.value.size===0){//防止用户移除原来的物料后更新错误
    currentAdCreative.value.size = oldAdCreative.value.size;
    currentAdCreative.value.duration = oldAdCreative.value.duration;
  }
  try {
    await UpdateAdCreative(currentAdCreative.value.creative_id, currentAdCreative.value);
    ElMessage.success('创意更新成功');
    await getAdCreatives();  // 刷新创意列表
    isEditDialogVisible.value = false;
  } catch (error) {
    ElMessage.error('更新创意失败，请稍后再试');
  }
};

// 格式化日期
const formatDate = (dateStr) => {
  if (!dateStr) return '';
  const date = new Date(dateStr);
  const year = date.getFullYear();
  const month = (date.getMonth() + 1).toString().padStart(2, '0');
  const day = date.getDate().toString().padStart(2, '0');
  return `${year}-${month}-${day}`;
};

function getMaterialType(creativeType) {
  const materialTypes = {
    0: 'BMP',
    1: 'JPG',
    2: 'PNG',
    3: 'MP4',
    4: 'AVI'
  };
  return materialTypes[creativeType] || '未知';
}

function formatDuration(seconds) {
  const hours = Math.floor(seconds / 3600);
  const minutes = Math.floor((seconds % 3600) / 60);
  const secs = seconds % 60;
  return `${hours.toString().padStart(2, '0')}:${minutes.toString().padStart(2, '0')}:${secs.toString().padStart(2, '0')}`;
}

function formatSize(size) {
  return `${(size / 1024).toFixed(2)} KB`
}


const uploadRef = ref()
const handleExceed = (files) => {
  uploadRef.value.clearFiles()
  const file = files[0]
  file.uid = genFileId()
  uploadRef.value.handleStart(file)
}

const dialogImgVisible = ref(false)
const dialogImgUrl = ref('');

// 预览功能
const handlePreview = (url) => {
  const fullUrl = `http://116.62.230.206:8888/${url}`;
  if (url.endsWith('.mp4') || url.endsWith('.avi')) {
    // 如果是视频，弹出视频预览对话框
    dialogImgUrl.value = fullUrl;
    dialogImgVisible.value = true;
  } else {
    // 如果是图片，弹出图片预览对话框
    dialogImgUrl.value = fullUrl;
    dialogImgVisible.value = true;
  }
};

// 下载功能
const handleDownload = (url) => {
  const fullUrl = `http://116.62.230.206:8888/${url}`;
  const link = document.createElement('a');
  link.href = fullUrl;
  link.download = url.split('/').pop(); // 使用文件名作为下载文件名
  document.body.appendChild(link);
  link.click();
  document.body.removeChild(link);
};

const onPreview = (file) => {
  dialogImgVisible.value = true
  dialogImgUrl.value = file.url
}
const video_url = ref()
const onRemove = () => {
  newAdCreative.value.size = 0
  newAdCreative.value.duration = 0
  video_url.value = ''
}
const onUpdateRemove = () => {
  currentAdCreative.value.size = 0
  currentAdCreative.value.duration = 0
  video_url.value = ''
}
// 处理文件变化（上传图片或视频后）
const handleUpdateFileChange = (file, fileList) => {
  if (file.status !== "ready") return;
  temp_file.value = file.raw

  const maxSize = 10 * 1024 * 1024;
  if (file.size > maxSize) {
    // 删除不符合条件的文件
    const index = fileList.findIndex(f => f.uid === file.uid);
    if (index !== -1) {
      fileList.splice(index, 1); // 从文件列表中移除不支持的文件
    }
    ElMessage.error('文件大小不能超过 10MB'); // 弹出提示框
    return false; // 如果文件太大，则停止后续处理
  }
  // 获取文件的扩展名
  const fileExtension = file.name.split('.').pop().toLowerCase();
  // 如果文件类型不在 materialTypeMap 中，则阻止上传
  const materialTypeMap = {
    bmp: 0,
    jpg: 1,
    png: 2,
    mp4: 3,
    avi: 4,
  };

  // 判断文件类型是否有效
  if (!(fileExtension in materialTypeMap)) {
    // 删除不符合条件的文件
    const index = fileList.findIndex(f => f.uid === file.uid);
    if (index !== -1) {
      fileList.splice(index, 1); // 从文件列表中移除不支持的文件
    }
    ElMessage.error('不支持的文件类型，请上传 JPG、PNG、BMP、MP4 或 AVI 格式的文件'); // 提示不支持的文件类型
    return false; // 阻止上传
  }

  // 处理文件的大小和时长
  currentAdCreative.value.size = file.size;
  currentAdCreative.value.material_type = materialTypeMap[fileExtension]; // 设置素材类型
  console.log(file)
  if (currentAdCreative.value.creative_type === 1) {
    // 手动生成临时 URL
    video_url.value = URL.createObjectURL(file.raw);
    // 视频处理
    const video = document.createElement('video');
    video.src = video_url.value;
    video.onloadedmetadata = () => {
      currentAdCreative.value.duration = Math.round(video.duration); // 获取视频时长
    };
  } else {
    // 图片不需要时长
    currentAdCreative.value.duration = 0;
  }
  return true
};
const handleFileChange = (file, fileList) => {
  if (file.status !== "ready") return;
  temp_file.value = file.raw

  const maxSize = 10 * 1024 * 1024;
  if (file.size > maxSize) {
    // 删除不符合条件的文件
    const index = fileList.findIndex(f => f.uid === file.uid);
    if (index !== -1) {
      fileList.splice(index, 1); // 从文件列表中移除不支持的文件
    }
    ElMessage.error('文件大小不能超过 10MB'); // 弹出提示框
    return false; // 如果文件太大，则停止后续处理
  }
  // 获取文件的扩展名
  const fileExtension = file.name.split('.').pop().toLowerCase();
  // 如果文件类型不在 materialTypeMap 中，则阻止上传
  const materialTypeMap = {
    bmp: 0,
    jpg: 1,
    png: 2,
    mp4: 3,
    avi: 4,
  };

  // 判断文件类型是否有效
  if (!(fileExtension in materialTypeMap)) {
    // 删除不符合条件的文件
    const index = fileList.findIndex(f => f.uid === file.uid);
    if (index !== -1) {
      fileList.splice(index, 1); // 从文件列表中移除不支持的文件
    }
    ElMessage.error('不支持的文件类型，请上传 JPG、PNG、BMP、MP4 或 AVI 格式的文件'); // 提示不支持的文件类型
    return false; // 阻止上传
  }

  // 处理文件的大小和时长
  newAdCreative.value.size = file.size;
  newAdCreative.value.material_type = materialTypeMap[fileExtension]; // 设置素材类型
  console.log(file)
  if (newAdCreative.value.creative_type === 1) {
    // 手动生成临时 URL
    video_url.value = URL.createObjectURL(file.raw);
    // 视频处理
    const video = document.createElement('video');
    video.src = video_url.value;
    video.onloadedmetadata = () => {
      newAdCreative.value.duration = Math.round(video.duration); // 获取视频时长
    };
  } else {
    // 图片不需要时长
    newAdCreative.value.duration = 0;
  }
  return true
};
onMounted(() => {
  getAdCreatives()
});
const searchText = ref(''); // 搜索关键词
// 处理搜索
const handleSearch = () => {
  currentPage.value = 1; // 搜索时重置到第一页
  getAdCreatives();
};
// 监听搜索关键词的变化，添加防抖
let searchTimeout = null;
watch(searchText, () => {
  clearTimeout(searchTimeout);
  searchTimeout = setTimeout(() => {
    handleSearch();
  }, 300); // 300ms 防抖
});


</script>

<template>
  <div class="ad-creative-container">
    <!-- 广告创意列表展示 -->
    <div class="action-bar">
      <el-button @click="toggleAdCreativeForm" type="primary">添加创意</el-button>
    </div>
    <div class="header">
      <h1>创意列表</h1>
      <!-- 搜索框 -->
      <div class="search-container">
        <el-input
            v-model="searchText"
            placeholder="请输入创意名称搜索"
            clearable
            @clear="handleSearch"
        >
          <template #append>
            <el-button @click="handleSearch" icon="el-icon-search"></el-button>
          </template>
        </el-input>
      </div>
      <!-- 排序选择 -->
      <div class="sort-container">
        <el-select v-model="sortField" placeholder="排序" @change="handleSortChange">
          <el-option label="创意名称" value="name"></el-option>
          <el-option label="创意类型" value="creative_type"></el-option>
          <el-option label="物料类型" value="material_type"></el-option>
          <el-option label="审核状态" value="audit_status"></el-option>
          <el-option label="高度" value="height"></el-option>
          <el-option label="宽度" value="width"></el-option>
          <el-option label="物料大小" value="size"></el-option>
          <el-option label="持续时长" value="duration"></el-option>
          <el-option label="创建时间" value="create_time"></el-option>
          <el-option label="修改时间" value="update_time"></el-option>
        </el-select>
      </div>

    </div>

    <!-- 表格展示创意列表 -->
    <el-table :data="adCreatives" style="width: 100%" stripe>
      <el-table-column label="创意名称" prop="name"></el-table-column>
      <el-table-column label="创意类型" prop="creative_type">
        <template #default="{ row }">
        <span>
          {{ row.creative_type === 0 ? '图片' : '视频' }}
          <span v-if="row.creative_type === 1">
        ({{ formatDuration(row.duration) }})
          </span>
        </span>
        </template>
      </el-table-column>
      <el-table-column label="审核状态" prop="audit_status">
        <template #default="{ row }">
          <span>{{ row.audit_status === 0 ? '已通过' : '未通过' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="物料类型" prop="material_type">
        <template #default="{ row }">
          <span>{{ getMaterialType(row.material_type) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="高度" prop="height"></el-table-column>
      <el-table-column label="宽度" prop="width"></el-table-column>
      <el-table-column label="大小" prop="size">
        <template #default="{ row }">
          <span>{{ formatSize(row.size) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="物料" prop="url" width="150px">
        <template #default="{ row }">
          <div v-if="row.url">
            <el-button type="text" @click="handlePreview(row.url)">预览</el-button>
            <el-button type="text" @click="handleDownload(row.url)">下载</el-button>
          </div>
          <span v-else>无物料</span>
        </template>
      </el-table-column>
      <el-table-column label="创作者" prop="user_name">
        <template #default="{ row }">
          <span>{{ row.user_name ? row.user_name : '未知创造者' }}</span>
        </template>
      </el-table-column>
      <el-table-column label="创建时间" prop="create_time">
        <template #default="{ row }">
          <span>{{ formatDate(row.create_time) }}</span>
        </template>
      </el-table-column>
      <el-table-column label="操作" align="center" width="200px">
        <template #default="{ row }">
          <el-button-group>
            <el-button @click="editAdCreative(row.creative_id)" type="primary" size="small">编辑</el-button>
            <el-button @click="deleteAdCreative(row.creative_id)" type="danger" size="small">删除</el-button>
          </el-button-group>
        </template>
      </el-table-column>
    </el-table>

    <!-- 分页控件 -->
    <el-pagination
        v-if="totalItems > 0"
        :current-page="currentPage"
        :page-size="pageSize"
        :total="totalItems"
        @current-change="handlePageChange"
        layout="total, prev, pager, next, jumper"
        class="custom-pagination"
    ></el-pagination>

    <el-dialog v-model="isAdCreativeFormVisible" title="添加创意" width="500px">
      <el-form ref="addAdCreativeRef" :model="newAdCreative" label-width="120px" class="ad-creative-form"
               :rules="rules">
        <el-form-item label="创意名称" :label-width="'120px'" prop="name">
          <el-input v-model="newAdCreative.name" placeholder="请输入创意名称"></el-input>
        </el-form-item>
        <!-- 宽度 -->
        <el-form-item label="宽度" prop="width">
          <el-input-number
              v-model="newAdCreative.width"
              :min="200"
              :max="4000"
              placeholder="请输入宽度"
              style="width: 100%;"
          />
        </el-form-item>
        <!-- 高度 -->
        <el-form-item label="高度" prop="height">
          <el-input-number
              v-model="newAdCreative.height"
              :min="200"
              :max="4000"
              placeholder="请输入高度"
              style="width: 100%;"
          />
        </el-form-item>
        <!-- 选择创意类型（图片或视频） -->
        <el-form-item label="选择创意类型" :label-width="'120px'">
          <el-radio-group v-model="newAdCreative.creative_type">
            <el-radio :label="0">图片</el-radio>
            <el-radio :label="1">视频</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 根据创意类型显示上传按钮 -->
        <el-form-item v-if="newAdCreative.creative_type === 0" label="上传图片">
          <el-upload
              ref="uploadRef"
              action="#"
              list-type="picture-card"
              :auto-upload="false"
              :multiple='false'
              :limit="1"
              :on-exceed="handleExceed"
              :on-preview="onPreview"
              :on-remove="onRemove"
              :on-change="handleFileChange"
              accept="image/*"
              class="upload-area"
          >
            <el-icon>
              <Plus/>
            </el-icon>
          </el-upload>
          <div class="upload-tip">请上传格式为 JPG、PNG、BMP 等图片文件。</div>
        </el-form-item>

        <el-form-item v-if="newAdCreative.creative_type === 1" label="上传视频">
          <el-upload
              ref="uploadRef"
              action="#"
              drag
              :auto-upload="false"
              :limit="1"
              :multiple='false'
              :on-exceed="handleExceed"
              :on-remove="onRemove"
              :on-change="handleFileChange"
              accept="video/*"
              class="upload-area"
          >
            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
            <div class="el-upload__text">
              Drop file here or <em>click to upload</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">
                请上传格式为 MP4、AVI 等视频文件。
              </div>
            </template>
          </el-upload>
          <!-- 视频上传后显示预览 -->
          <div v-if="video_url && newAdCreative.creative_type === 1">
            <video :src="video_url" controls class="preview-video"></video>
          </div>
        </el-form-item>

        <!-- 显示物料的大小 -->
        <el-form-item v-if="newAdCreative.size > 0" label="物料尺寸" :label-width="'120px'" prop="size">
          <span>{{ formatSize(newAdCreative.size) }}</span>
        </el-form-item>

        <!-- 显示视频的时长 -->
        <el-form-item v-if="newAdCreative.creative_type === 1 && newAdCreative.duration > 0" label="视频时长"
                      :label-width="'120px'">
          <span>{{ formatDuration(newAdCreative.duration) }}</span>
        </el-form-item>

      </el-form>

      <span slot="footer" class="dialog-footer">
      <el-button @click="isAdCreativeFormVisible = false">关闭</el-button>
      <el-button type="primary" @click="createAdCreative">添加</el-button>
    </span>
    </el-dialog>

    <!-- 编辑创意的表单 -->
    <el-dialog v-model="isEditDialogVisible" title="编辑创意">
      <el-form :model="currentAdCreative" label-width="100px">
        <el-form-item label="创意名称">
          <el-input v-model="currentAdCreative.name"></el-input>
        </el-form-item>
        <el-form-item label="高度">
          <el-input v-model="currentAdCreative.height"></el-input>
        </el-form-item>
        <el-form-item label="宽度">
          <el-input v-model="currentAdCreative.width"></el-input>
        </el-form-item>
        <!-- 选择创意类型（图片或视频） -->
        <el-form-item label="选择创意类型" :label-width="'120px'">
          <el-radio-group v-model="currentAdCreative.creative_type">
            <el-radio :label="0">图片</el-radio>
            <el-radio :label="1">视频</el-radio>
          </el-radio-group>
        </el-form-item>

        <!-- 根据创意类型显示上传按钮 -->
        <el-form-item v-if="currentAdCreative.creative_type === 0" label="上传图片">
          <el-upload
              ref="uploadRef"
              action="#"
              list-type="picture-card"
              :auto-upload="false"
              :multiple='false'
              :limit="1"
              :on-exceed="handleExceed"
              :on-preview="onPreview"
              :on-remove="onUpdateRemove"
              :on-change="handleUpdateFileChange"
              accept="image/*"
              class="upload-area"
          >
            <el-icon>
              <Plus/>
            </el-icon>
          </el-upload>
          <div class="upload-tip">请上传格式为 JPG、PNG、BMP 等图片文件。</div>
        </el-form-item>

        <el-form-item v-if="currentAdCreative.creative_type === 1" label="上传视频">
          <el-upload
              ref="uploadRef"
              action="#"
              drag
              :auto-upload="false"
              :limit="1"
              :multiple='false'
              :on-exceed="handleExceed"
              :on-remove="onUpdateRemove"
              :on-change="handleUpdateFileChange"
              accept="video/*"
              class="upload-area"
          >
            <el-icon class="el-icon--upload"><upload-filled /></el-icon>
            <div class="el-upload__text">
              Drop file here or <em>click to upload</em>
            </div>
            <template #tip>
              <div class="el-upload__tip">
                请上传格式为 MP4、AVI 等视频文件。
              </div>
            </template>
          </el-upload>
          <!-- 视频上传后显示预览 -->
          <div v-if="video_url && currentAdCreative.creative_type === 1">
            <video :src="video_url" controls class="preview-video"></video>
          </div>
        </el-form-item>

        <!-- 显示物料的大小 -->
        <el-form-item v-if="currentAdCreative.size > 0" label="物料尺寸" :label-width="'120px'" prop="size">
          <span>{{ formatSize(currentAdCreative.size) }}</span>
        </el-form-item>

        <!-- 显示视频的时长 -->
        <el-form-item v-if="currentAdCreative.creative_type === 1 && currentAdCreative.duration > 0" label="视频时长"
                      :label-width="'120px'">
          <span>{{ formatDuration(currentAdCreative.duration) }}</span>
        </el-form-item>
      </el-form>

      <span slot="footer" class="dialog-footer">
        <el-button @click="isEditDialogVisible = false">取消</el-button>
        <el-button type="primary" @click="updateAdCreative">更新</el-button>
      </span>
    </el-dialog>
    <!-- 预览对话框 -->
    <el-dialog v-model="dialogImgVisible" title="预览">
      <div v-if="dialogImgUrl.endsWith('.mp4') || dialogImgUrl.endsWith('.avi')">
        <video :src="dialogImgUrl" controls style="width: 100%;"></video>
      </div>
      <div v-else>
        <img :src="dialogImgUrl" alt="Preview Image" style="max-width: 100%;" />
      </div>
    </el-dialog>
  </div>
</template>

<style scoped lang="less">
.header {
  display: flex;
  align-items: center;
  justify-content: space-between;

  .sort-container {
    width: 200px;
  }
}

.el-button-group {
  display: flex;
  gap: 10px; /* 按钮之间的间距 */
  flex-wrap: wrap; /* 如果按钮过多，自动换行 */
}

/* 上传区域样式 */
.upload-area {
  margin-bottom: 10px;
}

/* 图片预览样式 */
.preview-img {
  width: 200px;
  height: 200px;
  object-fit: cover;
  margin-top: 10px;
}

/* 视频预览样式 */
.preview-video {
  width: 300px;
  height: 200px;
  margin-top: 10px;
}

/* 上传提示 */
.upload-tip {
  font-size: 12px;
  color: #999;
  margin-top: 5px;
}
/* 预览 */
.el-dialog__body {
  text-align: center; /* 居中显示预览内容 */
}
video, img {
  max-width: 100%;
  max-height: 80vh; /* 限制最大高度 */
}
</style>
